package magics
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;

	public class MagicSprite extends EventDispatcher implements ITickable
	{
		public static var END_OF_PLAY:String = "TGP_MAGICSPRITE_END_OF_PLAY";
		
		private var _displayObj:DisplayObject;
		private var _cacheTemplate:BitmapData;
		private var _cacheBmdVector:Vector.<BitmapData>;
		private var _initLoader:Loader;
		private var _magicCacheType:String = "mc";
		private var _container:Sprite;
		private var _magicUrl:String;
		
		private var _needInit:Boolean = false;
		private var _markForAdd:Boolean = false;
		private var _markForPlay:Boolean = false;
		private var _preBMDInit:Boolean = false;
		
		private var _curFrame:int = 0;
		private var _totalFrame:int = 0;
		
		private var _propertyCache:Array;
		
		private var _t:Matrix;
		
		//包括动画首次渲染为图片序列,只是控制类，不是显示类
		//图片序列存到外面去
		public function MagicSprite()
		{
			_t = new Matrix();
		}
		
		//初始化魔法
		public function initMagic(magicUrl:String,cacheType:String = "mc",cacheSize:Rectangle = null,preBMDInit:Boolean = false):void
		{
			_magicCacheType = cacheType;
			_preBMDInit = preBMDInit;
			_magicUrl = magicUrl;
			//如果有缓存从缓存读
			if(cacheType == "mc")
			{
				_displayObj = MagicCache.instance.getMCMagic(magicUrl);
				if(_displayObj!=null)
				{
					(_displayObj as MovieClip).gotoAndStop(1);
					_totalFrame = (_displayObj as MovieClip).totalFrames;
					_curFrame = 0;
				}
				else
				{
					_needInit = true;
				}
			}
			else if(cacheType == "bmd")
			{
				_cacheBmdVector = MagicCache.instance.getBMDMagic(magicUrl);
				if(_cacheBmdVector!=null)
				{
					_displayObj = new Bitmap();
					_totalFrame = _cacheBmdVector.length;
					_curFrame = 0
				}
				else
				{
					_cacheBmdVector = new Vector.<BitmapData>();
					_cacheTemplate = new BitmapData(cacheSize.width,cacheSize.height,true,0x00000000);
					_needInit = true;
					//如果预渲染提前添加到tickmanager中，否则使用mc播放，播放时渲染
				}
			}
			//如果没缓存根据类型初始化
			if(_needInit)
			{
				//播放,临时Loader
				var ldr:Loader = new Loader();
				ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,initLoadComplete);
				ldr.load(new URLRequest(magicUrl));
			}
			
		}
		//提供预渲染功能,临时的读取方式，正式应该用proxy读
		private function initLoadComplete(e:Event):void
		{
			_displayObj = e.target.content as DisplayObject;
			
			_displayObj = (_displayObj as MovieClip).getChildAt(0);
			var mc:MovieClip = (_displayObj as MovieClip);
			mc.stop();
			//mc.blendMode = BlendMode.ADD;
			_totalFrame = mc.totalFrames;
			_curFrame = 0;
			
			
			
			if(_magicCacheType == "mc")
			{
				MagicCache.instance.setMagic(_magicUrl,_magicCacheType,_displayObj);
				_needInit = false;
			}
			else if(_magicCacheType == "bmd")
			{
				if(_preBMDInit)
				{
					for(var i:int = 0;i<_totalFrame;i++)
					{
						mc.gotoAndStop(i+1);
						var bmd:BitmapData = _cacheTemplate.clone();
						_t.identity();
						_t.translate(_cacheTemplate.width/2,_cacheTemplate.height/2);
						bmd.draw(mc,_t);
						_cacheBmdVector.push(bmd);
					}
					MagicCache.instance.setMagic(_magicUrl,_magicCacheType,_cacheBmdVector);
					_displayObj = new Bitmap();
					_needInit = false;
					_preBMDInit = false;
				}
			}
			
			//赋值属性
			for(var p:String in _propertyCache)
			{
				setProperty(p,_propertyCache[p]);
			}
			_propertyCache = [];
			
					
			if(_markForAdd)
			{
				_markForAdd = false;
				addMagic(_container);	
				//_container = null;
			}
			
			if(_markForPlay)
			{
				play();
			}
			
		}
		
		private function resetBitmapProperties():void
		{
			
		}
		
		//此函数有装箱处理，影响效率，如果使用频繁考虑把类型修改为强制类型
		public function setProperty(propertyName:String,value:Object):void
		{
			if(_displayObj == null)
			{
				if(_propertyCache == null)
					_propertyCache = [];
				_propertyCache[propertyName] = value;
			}
			else
			{
				if(_displayObj.hasOwnProperty(propertyName))
				{
					if(_displayObj is Bitmap)
					{
						var num:Number;
						if(propertyName == "x")
						{
							num = value as Number;
							num -= _cacheBmdVector[0].width/2;
							value = num;
						}
						else if(propertyName == "y")
						{
							num = value as Number;
							num -= _cacheBmdVector[0].height/2;
							value = num;
						}
					}
					if(_displayObj[propertyName] != value)
					{
						
						_displayObj[propertyName] = value;
						
					}
				}
				else
				{
					//throw new Error("属性在目标对象上不存-.-#!");
				}
			}
			
		}
		
		
		public function get isAdded():Boolean
		{
			if(_container != null)
				return true;
			return false;
		}
		
		//把魔法加到舞台
		public function addMagic(container:Sprite):void
		{
			_container = container;
			if(_displayObj == null)
			{
				_markForAdd = true;
			}
			else
				container.addChild(_displayObj);
		}
		
		//可适应在添加完成前就被移除的情况
		public function removeMagic(container:Sprite):void
		{
			
			stop();
			_markForAdd = false;
			_markForPlay = false;
			_container = null;
			if(_displayObj!=null && container.contains(_displayObj))
				container.removeChild(_displayObj);
		}
		
		//获取魔法
		public function get displayObject():DisplayObject
		{
			return _displayObj;
		}
		
		
		public function play():void
		{
			if(_displayObj == null)
				_markForPlay = true;
			else
			{
				_curFrame = 0;
				if(_magicCacheType == "bmd")
					TickManager.instance.addObject(this);
				else if(_magicCacheType == "mc")
				{
					TickManager.instance.addObject(this);
					//(_displayObj as MovieClip).play();
				}
			}
		}
		
		public function stop():void
		{
			if(_displayObj == null)
				_markForPlay = false;
			else
			{

				if(_magicCacheType == "bmd")
				{
					TickManager.instance.removeObject(this);
				}
				else if(_magicCacheType == "mc")
				{
					TickManager.instance.removeObject(this);
				}
			}
		}
		
		public function update(step:int):void
		{
			if(_magicCacheType == "bmd")
			{
				if(_needInit)
				{
					var mc:MovieClip = _displayObj as MovieClip;
					mc.gotoAndStop(_curFrame+1);
					_curFrame++;
					var bmd:BitmapData = _cacheTemplate.clone();
					_t.identity();
					_t.translate(_cacheTemplate.width/2,_cacheTemplate.height/2);
					bmd.draw(mc,_t);
					_cacheBmdVector.push(bmd);
					if(_curFrame>=_totalFrame)
					{
						//用bmd替换原有mc
						var index:int = _container.getChildIndex(_displayObj);
						_container.removeChild(_displayObj);
						var oldDO:DisplayObject = _displayObj;
						_displayObj = new Bitmap();
						/*_displayObj.x = oldDO.x;
						_displayObj.y = oldDO.y;
						_displayObj.alpha = oldDO.alpha;
						_displayObj.rotation = oldDO.rotation
						_displayObj.scaleX = oldDO.scaleX;
						_displayObj.scaleY = oldDO.scaleY;
						_displayObj.blendMode = oldDO.blendMode;*/
						//_container.addChildAt(_displayObj,index);
						
						MagicCache.instance.setMagic(_magicUrl,_magicCacheType,_cacheBmdVector);
						dispatchEnd();
						_needInit = false;
					}
				}
				else
				{
					var bm:Bitmap = _displayObj as Bitmap;
					bm.bitmapData = _cacheBmdVector[_curFrame];
					_curFrame++;
					if(_curFrame>=_totalFrame)
					{
						dispatchEnd();
					}
				}
			}
			else if(_magicCacheType == "mc")
			{
				var mc:MovieClip = _displayObj as MovieClip;
				mc.gotoAndStop(_curFrame+1);
				_curFrame++;
				if(_curFrame>=_totalFrame)
				{
					dispatchEnd();
				}
			}
		}
		
		private function dispatchEnd():void
		{
			this.dispatchEvent(new Event(END_OF_PLAY));
			stop();
			if(_container!=null)
				this.removeMagic(_container);
			_curFrame = 0;
		}
		
		public function get tickType():int
		{
			return 0;
		}
		
		public function clear():void
		{

			if(_container != null)
				removeMagic(_container);
			stop();
			
			_displayObj = null;
			_cacheTemplate = null;
			_cacheBmdVector = null;
			_initLoader = null;//临时读取逻辑使用的loader
			_magicCacheType = "mc";
			_container = null
			_magicUrl = "";
			
			_needInit = false;
			_markForAdd = false;
			_markForPlay = false;
			_preBMDInit = false;
			
			_curFrame = 0;
			_totalFrame = 0;
			
			_propertyCache = null;
			
			_t.identity();
		}
		
		public function dispose():void
		{
			
		}
	}
}